using System;
using System.Collections.Generic;
using UnityEngine;

namespace GGameFramework
{
    public static class FrameworkEntry
    {
        private static readonly List<FrameworkModule> s_GameFrameworkModules = new List<FrameworkModule>();
        
        public static void Update(float elapseSeconds, float realElapseSeconds)
        {
            foreach (FrameworkModule gameFrameworkModule in FrameworkEntry.s_GameFrameworkModules)
                gameFrameworkModule.Update(elapseSeconds, realElapseSeconds);
        }

        /// <summary>
        /// 关闭所有系统模块
        /// </summary>
        public static void Shutdown()
        {
            FrameworkEntry.s_GameFrameworkModules.Clear();
        }
        
        /// <summary>获取游戏框架模块。</summary>
        /// <typeparam name="T">要获取的游戏框架模块类型。</typeparam>
        /// <returns>要获取的游戏框架模块。</returns>
        /// <remarks>如果要获取的游戏框架模块不存在，则自动创建该游戏框架模块。</remarks>
        public static T GetModule<T>() where T : FrameworkModule
        {
            Type type = typeof (T);
            // if (!type.IsInterface)
            //     throw new ($"You must get module by interface, but '{type.FullName}' is not.");
            // if (!type.FullName.StartsWith("GGameFramework.", StringComparison.Ordinal))
            //     throw new ($"You must get a GGame Framework module, but '{type.FullName}' is not.");
            string typeName = string.Concat(type.Namespace, ".", type.Name);
           
            return FrameworkEntry.GetModule(Type.GetType(typeName) ?? throw new ($"Can not find Game Framework module type '{typeName}'.")) as T;
        }

        private static FrameworkModule GetModule(Type moduleType)
        {
            foreach (FrameworkModule module in s_GameFrameworkModules)
            {
                if (module.GetType() == moduleType)
                {
                    return module;
                }
            }
            
            return FrameworkEntry.CreateModule(moduleType);
        }

        private static FrameworkModule CreateModule(Type moduleType)
        {
            FrameworkModule instance = (FrameworkModule) Activator.CreateInstance(moduleType);
            
            if (instance == null)
                throw new ($"Can not create module '{moduleType.FullName}'.");
            List<FrameworkModule> modules = FrameworkEntry.s_GameFrameworkModules;
            
            foreach (var module in modules)
            {
                if (module == instance)
                {
                    throw new Exception($"Module '{moduleType.FullName}' is already registered.");
                }
            }
            
            FrameworkEntry.s_GameFrameworkModules.Add(instance);
            FrameworkEntry.s_GameFrameworkModules.Sort((a, b) => a.Priority.CompareTo(b.Priority));
            
            return instance;
        }

    }

}

